/*
* Copyright 2010 Competentum group
*
* Licensed under the GNU General Public License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.competentum.lib.parser
{
	
	import com.competentum.lib.events.InputOutputDataEvent;
	
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.core.FlexGlobals;
	
	/**
	 * Manager that performs full job with flashvars and config-xml.
	 * You can specify encrypter with IXMLEncrypter interface if you want to encrypt some part of xml. If you don't need encryption set parameter as null.
	 * Parameter enableFileBrowsing:Boolean turns on appearance of browsing dialog if xml-file doesn't specified. 
	 * Due to internal security restrictions of flash player this dialog can be displayed only on key or mouse button press.
	 * defaultXML:XML with default parametrs.
	 * 
	 * @author Valentine Abanosimov
	 * */
	public class InputOutputManager extends EventDispatcher
	{
		private var flashVarsParser:IFlashVarsParser;
		private var dataParser:IDataParser;
		
		/**
		 * Does all the work with opening file
		 * */
		private var opener:Opener;
		/**
		 * Does all the work with saving to file
		 * */
		private var saver:ToFileSaver;
		private var dataEncrypter:IDataEncrypter;
		public var scope:*;

		public function InputOutputManager(flashVarsParser:IFlashVarsParser, dataParser:IDataParser, dataEncrypter:IDataEncrypter, opener:Opener, saver:ToFileSaver = null, target:IEventDispatcher=null)
		{
			super(target);
			this.flashVarsParser = flashVarsParser;
			this.dataParser = dataParser;
			this.dataEncrypter = dataEncrypter;
			if (opener)
			{
				this.opener = opener;
				opener.addEventListener(InputOutputDataEvent.CONFIGURATION_IS_LOADED, onLoaded);
			}
			else
			{
				opener = new Opener(null);
			}
			if (saver)
			{
				this.saver = saver;
			}
			else
			{
				saver = new ToFileSaver();
			}
			saver.addEventListener(InputOutputDataEvent.SAVED_TO_FILE, onSaved);
			saver.addEventListener(InputOutputDataEvent.SAVE_FAULT, redispatchEvent);
		}

		/**
		 * Public
		 * */
		public function load(scope:*, url:String = null):void
		{
			var xmlURL:String = (url == null) ? flashVarsParser.parse(FlexGlobals.topLevelApplication.parameters) : url;
			this.scope = scope;
			opener.openAIR(xmlURL);
		}
		
		public function saveToFile(scope:*):void
		{
			this.scope = scope;
			var data:String = dataParser.export(scope);
			if (dataEncrypter)
			{
				data = dataEncrypter.encrypt(data);
			}
			saver.saveToFileAIR(data, scope.filePath);
		}

		public function saveAsToFile(scope:*):void
		{
			this.scope = scope;
			var data:String = dataParser.export(scope);
			if (dataEncrypter)
			{
				data = dataEncrypter.encrypt(data);
			}
			saver.saveToFileAIR(data, null);
		}
		
		/**
		 * Private
		 * */
		private function onLoaded(event:InputOutputDataEvent):void
		{
			var data:String = (dataEncrypter) ? dataEncrypter.decrypt(event.data) : event.data;
			dataParser.parse(data, scope);
			redispatchEvent(event);
		}
		
		private function onSaved(event:InputOutputDataEvent):void
		{
			redispatchEvent(event);
		}
		
		private function redispatchEvent(event:InputOutputDataEvent):void
		{
			dispatchEvent(event.clone());
		}
	}
}